package com.cheer.service.impl;

import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheer.dao.UserDao;
import com.cheer.dto.UserAddDTO;
import com.cheer.dto.UserLockedDTO;
import com.cheer.dto.UserQueryDTO;
import com.cheer.dto.UserUpdateDTO;
import com.cheer.entity.User;
import com.cheer.enums.RoleEnum;
import com.cheer.exception.ServiceException;
import com.cheer.security.UserInfoHolder;
import com.cheer.service.UserService;
import com.cheer.vo.Page;
import com.cheer.vo.UserListVO;
import com.cheer.vo.UserVO;
import com.google.common.base.Objects;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Override
    public UserVO getCurrentUser() {
        User user = userInfoHolder.getUser();

        UserVO userVO = new UserVO();
        userVO.setName(user.getName());
        userVO.setUsername(user.getUsername());
        userVO.setRole(user.getRole());

        return userVO;
    }

    @Override
    public void updatePassword(String oldPassword, String newPassword) {
        Long id = userInfoHolder.getUser().getId();
        User user = userDao.selectById(id);
        if (user == null) {
            throw new ServiceException("帐号不存在");
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new ServiceException("旧密码输入错误");
        }

        User updateUser = new User().setId(user.getId()).setPassword(passwordEncoder.encode(newPassword));
        userDao.updateById(updateUser);
    }

    @Override
    public void reset(Long id) {
        User user = userDao.selectById(id);
        if (user == null || !Objects.equal(user.getRole(), RoleEnum.USER.getCode())) {
            throw new ServiceException("帐号不存在或当前账号权限过高，无法重置密码");
        }

        User updateUser = new User().setId(id).setPassword(passwordEncoder.encode("000000"));
        userDao.updateById(updateUser);
    }

    @Override
    public Page<UserListVO> listByPage(UserQueryDTO userQueryDTO) {
        IPage<User> page = userDao.selectPage(userQueryDTO.getPageNum(), userQueryDTO.getPageSize(),
                userQueryDTO.getKeyWord());
        List<UserListVO> userListVOList = page.getRecords().stream()
                .map(user -> new UserListVO()
                        .setId(user.getId())
                        .setName(user.getName())
                        .setUsername(user.getUsername())
                        .setSchoolName(user.getSchoolName())
                        .setApplicant(user.getApplicant())
                        .setProvince(user.getProvince())
                        .setLocked(user.getLocked())
                        .setLockedTime(user.getLockedTime()))
                .collect(Collectors.toList());
        return new Page<>(page, userListVOList);
    }

    @Override
    public void updateLocked(UserLockedDTO userLockedDTO) {
        User user = userDao.selectById(userLockedDTO.getId());
        if (user == null) {
            throw new ServiceException("帐号不存在");
        }

        Date updateLockedTime = user.getLocked() ? null : getLockedTime(userLockedDTO.getLockedTime());

        user.setLocked(!user.getLocked()).setLockedTime(updateLockedTime);
        userDao.updateUser(user);

    }

    @Override
    public void update(UserUpdateDTO userUpdateDTO) {
        if (userDao.selectById(userUpdateDTO.getId()) == null) {
            throw new ServiceException("帐号不存在");
        }

        Date lockedTime = getLockedTime(userUpdateDTO.getLockedTime());
        User updateUser = new User()
                .setId(userUpdateDTO.getId())
                .setName(userUpdateDTO.getName().trim())
                .setSchoolName(userUpdateDTO.getSchoolName().trim())
                .setProvince(userUpdateDTO.getProvince().trim())
                .setApplicant(userUpdateDTO.getApplicant().trim())
                .setLockedTime(lockedTime).setLocked(false);

        userDao.updateUser(updateUser);
    }

    @Override
    public void add(UserAddDTO userAddDTO) {
        if (userDao.selectOneByUsername(userAddDTO.getUsername()) != null) {
            throw new ServiceException("帐号已存在");
        }

        Date lockedTime = getLockedTime(userAddDTO.getLockedTime());
        User user = new User()
                .setUsername(userAddDTO.getUsername().trim())
                .setPassword(passwordEncoder.encode(userAddDTO.getPassword()))
                .setName(userAddDTO.getName().trim())
                .setRole(RoleEnum.USER.getCode())
                .setSchoolName(userAddDTO.getSchoolName().trim())
                .setProvince(userAddDTO.getProvince().trim())
                .setApplicant(userAddDTO.getApplicant().trim())
                .setLocked(false)
                .setLockedTime(lockedTime)
                .setDeleted(false);
        userDao.insert(user);
    }

    private Date getLockedTime(String timeStr) {
        if (StringUtils.isNotBlank(timeStr)) {
            try {
                DateTime dateTime = DateUtil.beginOfDay(DateUtil.parse(timeStr, "yyyy/M/d"));
                Date currentDate = DateUtil.beginOfDay(DateUtil.date());
                if (dateTime.getTime() <= currentDate.getTime()) {
                    throw new ServiceException("销毁时间不能早于当前日期，请重新输入");
                }
                return dateTime;
            } catch (DateException e) {
                throw new ServiceException("销毁时间不符合'yyyy/M/d'格式，请重新输入");
            }
        }
        return null;
    }

}